package com.nulldev.util.security.encryptAPI.streams;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;

import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.security.encryptAPI.Encryptor;

public class EncryptAPIOutputStream extends OutputStream {

	private final Encryptor enc;
	private final OutputStream os;

	public EncryptAPIOutputStream(final OutputStream original, final Encryptor enc) {
		if (enc == null)
			throw new NullPointerException("enc == null!");
		if (original == null)
			throw new NullPointerException("os == null");
		this.enc = enc;
		this.os = original;
	}

	@Override
	public void write(int b) throws IOException {
		throw new UnsupportedOperationException("Cannot write singular bytes!");
	}

	@Override
	public void write(byte[] b) throws IOException {
		final byte[] w = this.enc.encryptToBytes(b);
		this.os.write(w, 0, w.length);
	}

	@Override
	public void write(byte[] b, int off, int len) throws IOException {
		final byte[] w = this.enc.encryptToBytes(off <= 0 ? b : Arrays.copyOfRange(b, off, len));
		final byte[] p = new byte[4];
		MathUtil.putInt(w.length, p, 0);
		this.os.write(w);
		this.os.write(w, 0, w.length);
	}

	@Override
	public void close() throws IOException {
		this.os.close();
	}

	@Override
	public void flush() throws IOException {
		this.os.flush();
	}
}
